package net.lengwang.iot.middleware.packet;

import lombok.Data;
import lombok.ToString;

import java.time.LocalDateTime;
import java.util.Arrays;

@Data
@ToString
public class ParsedPacket {
    // 原始字节数据
    private byte[] rawData;
    // 解析后的十六进制字符串数据
    private String parsedData;
    // 数据包起始标志
    private String startFlag;
    // 数据包长度
    private String length;
    // 命令类型
    private String command;
    // 命令名称
    private String commandName;
    // 协议版本
    private String version;
    // 序列号
    private String sequenceNumber;
    // 设备ID，可能为空
    private String deviceId = null;
    // 电压值
    private double voltage;
    // 信号强度
    private String signalStrength;
    // 时间信息
    private String time;
    // CRC16校验码
    private String crc16;
    // 数据包结束标志
    private String endFlag;
    // 协议版本
    private String protocolVersion;
    // 连接ID
    private String connectionId;

    // 新增字段
    // 设备类型
    private String deviceType;
    // 网关ID
    private String gatewayId;
    // 网关上传时间
    private String gatewayUploadTime;
    // NTP是否成功
    private String ntpOk;
    // 网关是否正在充电
    private boolean gatewayCharging;
    // 网关电压
    private double gatewayVoltage;
    // 软件主版本号
    private int softwareMajorVersion;
    // 软件次版本号
    private int softwareMinorVersion;
    // 客户代码
    private int customerCode;
    // 调试信息
    private String debugInfo;
    // 工作模式
    private int workMode;
    // 转发策略
    private int forwardingStrategy;
    // 预期绑定数
    private int expectedBindings;
    // 实际绑定数
    private int actualBindings;
    // 接收到的SS计数
    private int receivedSSCount;
    // 网络类型
    private int networkType;
    // SIM卡MSIN
    private long simMsin;
    // 信号质量
    private int csq;
    // 误码率
    private int bitErrorRate;
    // 重启原因
    private int restartReason;
    // RAM使用情况
    private int ram;
    // P-flash存储计数
    private long pflashStoredCount;
    // 保留字段
    private String reserved;

    public String getByte(int index) {
        // EB EB 04 90 01 01 A2 00 00 BE BE 每2个字符位一组,如EB EB 04的04是index=3的，则返回04
        if (index % 2 == 0) {
            return String.valueOf(rawData[index]);
        }
        return String.valueOf(rawData[index]);
    } 
    /**
     * 根据Modbus协议的常用读法获取指定位置的字节数据，索引从1开始
     * 默认读取一个字节（两个十六进制字符）
     * 
     * @param startIndex 起始索引（从1开始）
     * @return 两个字符组成的字节数据
     */
    public String getModbusByte(int startIndex) {
        return getModbusBytes(startIndex, 1);
    }

    /**
     * 根据Modbus协议的常用读法获取指定范围的字节数据，索引从1开始
     * 
     * @param startIndex 起始索引（从1开始）
     * @param byteCount  字节数量
     * @return 指定范围的字节数据
     */
    public String getModbusBytes(int startIndex, int byteCount) {
        int adjustedIndex = (startIndex - 1) * 2;
        if (adjustedIndex < 0 || adjustedIndex + byteCount * 2 > parsedData.length()) {
            throw new IndexOutOfBoundsException("索引范围超出数据长度" + parsedData.length() + " >> " + parsedData.toString());
        }
        return parsedData.substring(adjustedIndex, adjustedIndex + byteCount * 2);
    }

    /**
     * 根据Modbus协议的常用读法获取指定范围的整数值，索引从1开始
     * 默认读取一个字节（两个十六进制字符）
     * 
     * @param startIndex 起始索引（从1开始）
     * @return 转换后的整数值
     */
    public int getModbusInt(int startIndex) {
        return getModbusInt(startIndex, 1);
    }

    /**
     * 根据Modbus协议的常用读法获取指定范围的整数值，索引从1开始
     * 
     * @param startIndex 起始索引（从1开始）
     * @param byteCount  字节数量
     * @return 转换后的整数值
     */
    public int getModbusInt(int startIndex, int byteCount) {
        String hexValue = getModbusBytes(startIndex, byteCount);
        return Integer.parseInt(hexValue, 16);
    }

    /**
     * 根据Modbus协议的常用读法获取指定范围的长整数值，索引从1开始
     * 默认读取4个字节（8个十六进制字符）
     * 
     * @param startIndex 起始索引（从1开始）
     * @return 转换后的长整数值
     */
    public long getModbusLong(int startIndex) {
        return getModbusLong(startIndex, 4);
    }

    /**
     * 根据Modbus协议的常用读法获取指定范围的长整数值，索引从1开始
     * 
     * @param startIndex 起始索引（从1开始）
     * @param byteCount  字节数量
     * @return 转换后的长整数值
     */
    public long getModbusLong(int startIndex, int byteCount) {
        String hexValue = getModbusBytes(startIndex, byteCount);
        return Long.parseLong(hexValue, 16);
    }
}
